package com.codeduck.service;

import com.codeduck.utils.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.stereotype.Service;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author: <a href="mailto:codeduck@163.com">codeduck</a>
 * @date: 2023/01/07
 */
@Service
@Slf4j
public class HealthCheckService {

    private static final String SQL = "select 1 from dual";

    public int dbCheck(String idx) {
        int flag = 0;
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            DataSource dataSource = null;
            if ("1".equals(idx)) {
                dataSource = getDataSourceWithInitialContext();
            } else if ("2".equals(idx)) {
                dataSource = getDataSourceWithJndiDataSourceLookup();
            } else if ("3".equals(idx)){
                dataSource = getDataSourceWithJndiObjectFactoryBean();
            } else {
                dataSource = SpringBeanUtil.getBean("mysqlDataSource");
            }
            connection = dataSource.getConnection();
            statement = connection.createStatement();

            for (rs = statement.executeQuery(SQL); rs.next(); flag = 0) {
            }
        } catch (Exception e) {
            flag = -1;
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                flag = -1;
                e.printStackTrace();
            }
        }
        return flag;
    }

//    @Resource
//    private DataSource source;
//    private DataSource getDataSourceBySpringIOC() {
//        return source;
//    }

    private DataSource getDataSourceWithJndiObjectFactoryBean() throws NamingException {
        JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
        // jndiName 的前缀必须为 java:comp/env/
        factoryBean.setJndiName("java:comp/env/mysqlDataSource");
        factoryBean.setProxyInterface(DataSource.class);
        factoryBean.setLookupOnStartup(false);
        factoryBean.afterPropertiesSet();
        log.info("@@@@@@@@@@@@@@@@by JndiObjectFactoryBean @@@@@@@@@@@@@@@@@@");
        return (DataSource) factoryBean.getObject();
    }

    private DataSource getDataSourceWithInitialContext() throws NamingException {
        // javax.naming.InitialContext 方式获取数据源，jndiName的环境标识前缀必须为 java:comp/env/
        InitialContext ctx = new InitialContext();
        DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/mysqlDataSource");
        log.info("@@@@@@@@@@@@@@@@by InitialContext @@@@@@@@@@@@@@@@@@");

        return dataSource;
    }

    private DataSource getDataSourceWithJndiDataSourceLookup() {
        // org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup 方式获取数据源
        // jndiName 不能为 java:comp/env/jdbc/
        // 可以是：
        // 1. java:comp/env/mysqlDataSource
        // 2. mysqlDataSource（当不以java:comp/env/为前缀 && jndiName中不包含 : 时，spring会主动拼接 java:comp/env/）
        JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = jndiDataSourceLookup.getDataSource("mysqlDataSource");
        log.info("@@@@@@@@@@@@@@@@by JndiDataSourceLookup @@@@@@@@@@@@@@@@@@");
        return dataSource;
    }

    public int fsCheck() {
        File file = new File("hello.txt");
        FileWriter fw = null;
        BufferedWriter bw = null;
        int flag = 0;
        try {
            fw = new FileWriter(file);
            bw = new BufferedWriter(fw);
            bw.write("hello world!");
        } catch (IOException e) {
            flag = -1;
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
                if (fw != null) {
                    fw.close();
                }
                if (file.exists()) {
                    file.delete();
                }
            } catch (IOException e) {
                flag = -1;
                e.printStackTrace();
            }
        }
        return flag;
    }
}
